home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 22 / PC Actual CD 22.iso / linux / xfree86 / DOC / VGADriver.Doc < prev    next >
Encoding:
Text File  |  1998-01-07  |  42.7 KB  |  1,387 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.              How to add an (S)VGA driver to XFree86
  11.  
  12.           Copyright (c) 1993, 1994 David E. Wexelblat
  13.                    <dwex@XFree86.org>
  14.  
  15.                 Issue 1.3 - May 29, 1994
  16.  
  17.  
  18.  
  19. 1.  Introduction
  20.  
  21. Adding support for a new SVGA chipset to XFree86 is a challenging project for
  22. someone who wants to learn more about hardware-level programming.  It can be
  23. fraught with hazards (in particular, crashing the machine is all too common).
  24. But in the end, when the server comes up and functions, it is immensely satis-
  25. fying.
  26.  
  27. Adding support for an SVGA chipset does not change any of the basic functioning
  28. of the server.    It is still a dumb 8-bit PseudoColor server or 1-bit StaticGray
  29. server.  Adding support for new hardware (e.g. accelerated chips) is a major
  30. undertaking, and is not anywhere near formalized enough yet that it can be doc-
  31. umented.
  32.  
  33. Nonetheless, the driver-level programming here is a good introduction.    And can
  34. well be the first step for adding support for an accelerated chipset, as many
  35. are SVGA-supersets.  Writing an SVGA-level driver for the chipset can provide a
  36. stable development platform for making use of new features (in fact, this has
  37. been done for the S3, Cirrus, and WD accelerated chipsets, for internal use as
  38. the accelerated servers are developed for XFree86 2.0).
  39.  
  40. Now let's get down to it.  In addition to this documentation, a stub driver has
  41. been provided.    This should provide you a complete framework for your new
  42. driver.  Don't let the size of this document persuade you that this is an
  43. overly difficult task.    A lot of work has been put into making this document as
  44. close to complete as possible; hence it should, in theory, be possible to use
  45. this as a cookbook, and come out with a working driver when you reach the end.
  46. I do advise that you read it all the way through before starting.
  47.  
  48.  
  49. 2.  Getting Started
  50.  
  51. The first step in developing a new driver is to get the documentation for your
  52. chipset.  I've included a list of vendor contact information that I have col-
  53. lected so far (it's far from complete, so if you have any that isn't on the
  54. list, please send it to me).  You need to obtain the databook for the chipset.
  55. Make sure that the person you speak to is aware that you intend to do register-
  56. level programming (so they don't send you the EE-style datasheet).  Ask for any
  57. example code, or developer's kits, etc.  I've learned that at the SVGA level,
  58. in general, a databook that lists and describes the registers is the most you
  59. can hope to find.
  60.  
  61. If you are not familiar with VGA register-level programming, you should get
  62.  
  63.  
  64.  How to add an (S)VGA driver to XFree86
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  How to add an (S)VGA driver to XFree86
  71.  
  72.  
  73.  
  74. (and read!) a copy of Richard Ferraro's bible (see references below).  The best
  75. way to understand what is happening in the server is to study the workings of
  76. the monochrome server's ``generic'' server, and compare it with the documenta-
  77. tion in Ferraro's book (be aware that there are a few errors in the book).  You
  78. can find the generic-VGA-register handling functions in the file ``vgaHW.c''.
  79.  
  80. Once you understand what's happening in the generic server, you should study
  81. one or more of the existing SVGA drivers.  Obtain the databook for a supported
  82. SVGA chipset, and study the documentation along with the code.    When you have a
  83. good understanding of what that driver does over and above the generic VGA, you
  84. will know what information you need to obtain from the databook for the new
  85. chipset.  Once you have this information, you are ready to begin work on your
  86. new driver.
  87.  
  88.  
  89. 3.  Directory Tree Structure
  90.  
  91. Here is an outline of the directory tree structure for the source tree.  Only
  92. directories/files that are relevant to writing a driver are presented.    The
  93. structure for the Link Kit is presented below.
  94.  
  95.       xc/config/cf/
  96.  
  97.           site.def
  98.             Local configuration customization
  99.  
  100.           xf86site.def
  101.             XFree86 local configuration customization
  102.  
  103.       xc/programs/Xserver/hw/xfree86/
  104.         The server source
  105.  
  106.           common/
  107.             Files common to all of the server (XF86Config parser,
  108.             I/O device handlers, etc)
  109.  
  110.                   xf86.h
  111.                     Contains the `ScrnInfoRec' data structure
  112.  
  113.                   xf86_Option.h
  114.                     Contains option flags
  115.  
  116.                   compiler.h
  117.                     Contains in-line assembler macros and util-
  118.                     ity functions
  119.  
  120.           os-support/
  121.             OS-support layer
  122.  
  123.                   assyntax.h
  124.                     Contains macro-ized assembler mnemonics
  125.  
  126.                   xf86_OSlib.h
  127.                     OS-support includes, defines, and
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  How to add an (S)VGA driver to XFree86
  137.  
  138.  
  139.  
  140.                     prototypes
  141.  
  142.           LinkKit/
  143.  
  144.                   site.def.LK
  145.                     Template for Link Kit site.def
  146.  
  147.           vga256/
  148.             256-color VGA server directories
  149.  
  150.                   vga/
  151.                     The generic VGA handling code
  152.  
  153.                       vga.h
  154.                         Contains the `vgaVideoChipRec'
  155.                         and `vgaHWRec' data structures
  156.  
  157.                       vgaHW.c
  158.                         Contains the generic-VGA-regis-
  159.                         ter handling functions vgaH-
  160.                         WInit(), vgaHWSave() and vgaH-
  161.                         WRestore().
  162.  
  163.                   drivers/
  164.                     Contains the SVGA driver subdirectories.
  165.                     Each contains an Imakefile, a .c file for
  166.                     the driver, and a .s file for the bank-
  167.                     switching functions.
  168.  
  169.           vga2/
  170.             The monochrome vga server directories.    Most of the
  171.             files are linked from vga256, and the differences han-
  172.             dled by conditional compilation.
  173.  
  174.                   drivers/
  175.                     The SVGA driver subdirectories.  The
  176.                     `generic' VGA driver is also located here.
  177.  
  178.           vga16/
  179.             The 16-color vga server directories.  Most of the files
  180.             are linked from vga256, and the differences handled by
  181.             conditional compilation.
  182.  
  183.                   drivers/
  184.                     The SVGA driver subdirectories.
  185.  
  186.           VGADriverDoc/
  187.             This documentation and the stub driver.
  188.  
  189. The Link Kit is usually installed in /usr/X11R6/lib/Server.  The Link Kit con-
  190. tains everything that is needed to relink the server.  It is possible to write
  191. a new driver and build a new server without having even the server source
  192. installed.
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  How to add an (S)VGA driver to XFree86
  203.  
  204.  
  205.  
  206.       Server/
  207.  
  208.           site.def
  209.             Local configuration customization
  210.  
  211.           include/
  212.             All of the include files listed under the `common'
  213.             directory above
  214.  
  215.           drivers/
  216.             All of the SVGA drivers
  217.  
  218.                   vga2/
  219.                     The SVGA driver subdirectories.
  220.  
  221.                   vga16/
  222.                     The SVGA driver subdirectories.
  223.  
  224.                   vga256/
  225.                     The SVGA driver subdirectories.
  226.  
  227.           VGADriverDoc/
  228.             The directory with this documentation and the stub
  229.             driver.  `vgaHW.c' is also copied here, for reference
  230.             (it is not built as part of the Link Kit).
  231.  
  232.  
  233. 4.  Setting Up The Build Information
  234.  
  235. This section describes the peripheral configuration and build steps that must
  236. be performed to set up for your new driver.  The steps are the same whether you
  237. are building from the source tree of from the Link Kit; only the locations of
  238. the files is different.  Here are the configuration steps that must be fol-
  239. lowed:
  240.  
  241.   1.        Choose the name for your driver subdirectory and data structures.
  242.       Since the current driver scheme allows (in fact, encourages) putting
  243.       drivers for multiple related chipsets in a single driver, it is usually
  244.       best to use the vendor name, rather than a chipset version.  The fact
  245.       that older XFree86 drivers do not follow this convention should not deter
  246.       you from using it now - most of that code was developed before the driver
  247.       interface had been made flexible and extensible.
  248.  
  249.       For this documentation, we'll use chips from the SuperDuper Chips vendor.
  250.       Hence, we'll use `sdc' for the name of the driver.
  251.  
  252.   2.        Decide whether your driver will support the color server, the
  253.       monochrome server, or both.  For this documentation, we will assume that
  254.       both the color and monochrome servers will be supported.    If you intend
  255.       to support only the color server, the steps for the monochrome server can
  256.       be ignored.  If you intend to support only the monochrome server, the
  257.       steps for the color server listed should be performed for the monochrome
  258.       server, and the monochrome steps ignored.  Most of the existing drivers
  259.       support only the color or both servers; the ``generic'' driver is the
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  How to add an (S)VGA driver to XFree86
  269.  
  270.  
  271.  
  272.       only driver (currently) that supports just the monochrome server.
  273.  
  274.   3.        Create your driver directories:
  275.  
  276.  
  277.      o If you are working in the source tree, create the following directo-
  278.        ries:
  279.  
  280.  
  281.            xc/programs/Xserver/hw/xfree86/vga256/drivers/sdc
  282.            xc/programs/Xserver/hw/xfree86/vga16/drivers/sdc
  283.            xc/programs/Xserver/hw/xfree86/vga2/drivers/sdc
  284.  
  285.  
  286.  
  287.      o If you are working in the Link Kit, create the following directo-
  288.        ries:
  289.  
  290.            /usr/X11R6/lib/Server/drivers/vga256/sdc
  291.            /usr/X11R6/lib/Server/drivers/vga16/sdc
  292.            /usr/X11R6/lib/Server/drivers/vga2/sdc
  293.  
  294.  
  295.  
  296.   4.        Set up the Imakefile parameters to cause your driver to be built:
  297.  
  298.  
  299.      o If you are working in the source tree:
  300.  
  301.          1.  Edit the file xc/config/cf/xfree86.cf, and add `sdc' to the
  302.          list for the definitions for `XF86Vga256Drivers',
  303.          `XF86Vga16Drivers' and `XF86Vga2Drivers'.  You should put
  304.          `sdc' just before `generic' in the list (i.e. second last), to
  305.          ensure that none of the other driver's probe functions incor-
  306.          rectly detect the `sdc' chipset .
  307.  
  308.          2.  Edit the file xc/config/cf/xf86site.def, and add the same
  309.          entries in this file (this is just a comment that shows the
  310.          default values).
  311.  
  312.          3.  Edit the site.def.LK file in xc/pro-
  313.          grams/Xserver/hw/xfree86/LinkKit/, and add the same entries in
  314.          this file.  This is the prototype `site.def' file that will be
  315.          installed in the Link Kit.
  316.  
  317.  
  318.  
  319.      o If you are working in the Link Kit, edit the file
  320.        /usr/X11R6/lib/Server/site.def, and add `sdc' to the
  321.        `XF86Vga256Drivers', `XF86Vga16Drivers' and `XF86Vga2Drivers' defi-
  322.        nitions as described in (a) above.
  323.  
  324.   5.        Now copy the prototype files into your new directories:
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  How to add an (S)VGA driver to XFree86
  335.  
  336.  
  337.  
  338.      o If you are working in the source tree, copy the `stub' files as fol-
  339.        lows (directories are below xc/programs/Xserver):
  340.  
  341.          Imakefile.stub =>
  342.                hw/xfree86/vga256/drivers/sdc/Imakefile
  343.  
  344.          stub_driver.c =>
  345.                hw/xfree86/vga256/drivers/sdc/sdc_driver.c
  346.  
  347.          stub_bank.s =>
  348.                hw/xfree86/vga256/drivers/sdc/sdc_bank.s
  349.  
  350.          Imakefile.stub =>
  351.                hw/xfree86/vga16/drivers/sdc/Imakefile (then edit this
  352.                Imakefile and make the changes described in the com-
  353.                ments).
  354.  
  355.          Imakefile.stub =>
  356.                hw/xfree86/vga2/drivers/sdc/Imakefile (then edit this
  357.                Imakefile and make the changes described in the com-
  358.                ments).
  359.  
  360.      o If you are working in the Link Kit, copy the `stub' files as fol-
  361.        lows:
  362.  
  363.          Imakefile.stub =>
  364.                /usr/X11R6/lib/Server/drivers/vga256/sdc/Imakefile
  365.  
  366.          stub_driver.c =>
  367.                /usr/X11R6/lib/Server/drivers/vga256/sdc/sdc_driver.c
  368.  
  369.          stub_bank.s =>
  370.                /usr/X11R6/lib/Server/drivers/vga256/sdc/sdc_bank.s
  371.  
  372.          Imakefile.stub =>
  373.                /usr/X11R6/lib/Server/drivers/vga16/sdc/Imakefile (then
  374.                edit this Imakefile and make the changes described in
  375.                the comments).
  376.  
  377.          Imakefile.stub =>
  378.                /usr/X11R6/lib/Server/drivers/vga2/sdc/Imakefile (then
  379.                edit this Imakefile and make the changes described in
  380.                the comments).
  381.  
  382.   6.        Edit each of the files you've just copied, and replace `stub' with
  383.       `sdc' and `STUB' with `SDC' wherever they appear.
  384.  
  385. That's all the prep work needed.  Now it's time to work on the actual driver.
  386.  
  387.  
  388. 5.  The Bank-Switching Functions
  389.  
  390. The normal VGA memory map is 64k starting at address 0xA0000.  To access more
  391. than 64k of memory, SuperVGA chipsets implement ``bank switching'' - the high-
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  How to add an (S)VGA driver to XFree86
  401.  
  402.  
  403.  
  404. order address bits are used to select the bank of memory in which operations
  405. will take place.  The size and number of these banks varies, and will be
  406. spelled out in the chipset documentation.  A chipset will have zero, one or two
  407. bank registers.  Likely the ONLY case of zero bank registers is a generic VGA,
  408. and hence is not a concern.
  409.  
  410. Note that some of the newer chipsets (e.g. Trident 8900CL, Cirrus) allow for a
  411. linear mapping of the video memory.  While using such a scheme would improve
  412. the performance of the server, it is not currently supported.  Hence there is
  413. no way to use such features for a new chipset.
  414.  
  415. Most SVGA chipsets have two bank registers.  This is the most desirable struc-
  416. ture (if any banking structure can be called ``desirable''), because data can
  417. be moved from one area of the screen to another with a simple `mov' instruc-
  418. tion.  There are two forms of dual-banking - one where the two bank operations
  419. define a read-only bank and a write-only bank, and one with two read/write win-
  420. dows.  With the first form, the entire SVGA memory window is used for both read
  421. a write operations, and the two bank registers determine which bank is actually
  422. used (e.g. ET3000, ET4000).  With the second form, the SVGA memory window is
  423. split into two read/write banks, with each bank pointer being used to control
  424. one window.  In this case, one window is used for read operations and the other
  425. for write operations (e.g. PVGA1/Western Digital, Cirrus).
  426.  
  427. A chipset that has a single bank register uses that one bank for both read and
  428. write access.  This is problematic, because copying information from one part
  429. of the screen to another requires that the data be read in, stored, and then
  430. written out.  Fortunately, the server is able to handle both one-bank and two-
  431. bank chipsets; the determination of behavior is defined by an entry in the
  432. driver data structure described below.
  433.  
  434. A driver requires that three assembly-language functions be written, in the
  435. file `sdc_bank.s'.  These functions set the read bank - SDCSetRead(), the write
  436. bank - SDCSetWrite(), and set both banks - SDCSetReadWrite().  For a chipset
  437. with only one bank, all three will be declared as entry points to the same
  438. function (see the ``tvga8900'' driver for an example).
  439.  
  440. The functions are fairly simple - the bank number is passed to the function in
  441. register %al.  The function will shift, bitmask, etc - whatever is required to
  442. put the bank number into the correct form - and then write it to the correct
  443. I/O port.  For chipsets where the two banks are read-only HERE and write-only,
  444. the SetReadWrite() function will have to do this twice - once for each bank.
  445. For chipsets with two independent read/write windows, the SetReadWrite() func-
  446. tion should use the same bank as the SetWrite() function.
  447.  
  448. A special note - these functions MUST be written in the macroized assembler
  449. format defined in the header file ``assyntax.h''.  This will ensure that the
  450. correct assembler code will be generated, regardless of OS.  This macroized
  451. format currently supports USL, GNU, and Intel assembler formats.
  452.  
  453. That's all there is to the banking functions.  Usually the chipset reference
  454. will give examples of this code; if not, it is not difficult to figure out,
  455. especially using the other drivers as examples.
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  How to add an (S)VGA driver to XFree86
  467.  
  468.  
  469.  
  470. 6.  The Driver Itself
  471.  
  472. Now it's time to get down to the real work - writing the major driver functions
  473. in the files sdc_driver.c.  First, an overview of what the responsibilities of
  474. the driver are:
  475.  
  476.   1.          Provide a chipset-descriptor data structure to the server.  This
  477.       data structure contains pointers to the driver functions and some data-
  478.       structure initialization as well.
  479.  
  480.   2.          Provide a driver-local data structure to hold the contents of the
  481.       chipset registers.  This data structure will contain a generic part and a
  482.       driver-specific part.  It is used to save the initial chipset state, and
  483.       is initialized by the driver to put the chipset into different modes.
  484.  
  485.   3.          Provide an identification function that the server will call to
  486.       list the chipsets that the driver is capable of supporting.
  487.  
  488.   4.          Provide a probe function that will identify this chipset as dif-
  489.       ferent from all others, and return a positive response if the chipset
  490.       this driver supports is installed, and a negative response otherwise.
  491.  
  492.   5.          Provide a function to select dot-clocks available on the board.
  493.  
  494.   6.          Provide functions to save, restore, and initialize the driver-
  495.       local data structure.
  496.  
  497.   7.          Provide a function to set the starting address for display in the
  498.       video memory.  This implements the virtual-screen for the server.
  499.  
  500.   8.          Perhaps provide a function for use during VT-switching.
  501.  
  502.   9.          Perhaps provide a function to check if each mode is suitable for
  503.       the chipset being used.
  504.  
  505. Before stepping through the driver file in detail, here are some important
  506. issues:
  507.  
  508.   1.          If your driver supports both the color and monochrome servers,
  509.       you should take care of both cases in the same file.  Most things are the
  510.       same - you can differentiate between the two with the MONOVGA #define.
  511.       If the 16 color server is supported, code specific to it can be enabled
  512.       with the XF86VGA16 #define.  In most cases  it is sufficient to put the
  513.       following near the top of the stub_driver.c file:
  514.  
  515.  
  516.           #ifdef XF86VGA16
  517.           #define MONOVGA
  518.           #endif
  519.  
  520.  
  521.  
  522.   2.          The color server uses the SVGA's 8-bit packed-pixel mode.  The
  523.       monochrome and vga16 servers uses the VGA's 16-color mode (4 bit-planes).
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  How to add an (S)VGA driver to XFree86
  533.  
  534.  
  535.  
  536.       Only one plane is enabled for the monochrome server.
  537.  
  538.   3.          It is possible for you to define your monochrome driver so that
  539.       no bank-switching is done.  This is not particularly desirable, as it
  540.       yields only 64k of viewing area.
  541.  
  542. Keeping these things in mind, you need to find the registers from your SVGA
  543. chipset that control the desired features.  In particular, registers that con-
  544. trol:
  545.  
  546.   1.          Clock select bits.  The two low-order bits are part of the stan-
  547.       dard Miscellaneous Output Register; most SVGA chipsets will include 1 or
  548.       2 more bits, allowing the use of 8 or 16 discrete clocks.
  549.  
  550.   2.          Bank selection.  The SVGA chipset will have one or two registers
  551.       that control read/write bank selection.
  552.  
  553.   3.          CRTC extensions.    The standard VGA registers don't have enough
  554.       bits to address large displays.  So the SVGA chipsets have extension
  555.       bits.
  556.  
  557.   4.          Interlaced mode.    Standard VGA does not support interlaced dis-
  558.       plays.  So the SVGA chipset will have a bit somewhere to control inter-
  559.       laced mode.  Some chipsets require additional registers to be set up to
  560.       control interlaced mode
  561.  
  562.   5.          Starting address.  The standard VGA only has 16 bits in which to
  563.       specify the starting address for the display.  This restricts the screen
  564.       size usable by the virtual screen feature.  The SVGA chipset will usually
  565.       provide one or more extension bits.
  566.  
  567.   6.          Lock registers.  Many SVGA chipset prevent modification of
  568.       extended registers unless the registers are first ``unlocked''.  You will
  569.       need to disable protection of any registers you will need for other pur-
  570.       poses.
  571.  
  572.   7.          Any other facilities.  Some chipset may, for example, require
  573.       that certain bits be set before you can access extended VGA memory
  574.       (beyond the IBM-standard 256k).  Or other facilities; read through all of
  575.       the extended register descriptions and see if anything important leaps
  576.       out at you.
  577.  
  578. If you are fortunate, the chipset vendor will include in the databook some
  579. tables of register settings for various BIOS modes.  You can learn a lot about
  580. what manipulations you must do by looking at the various BIOS modes.
  581.  
  582. 6.1  Multiple Chipsets And Options
  583.  
  584. It is possible, and in fact desirable, to have a single driver support multiple
  585. chipsets from the same vendor.    If there are multiple supported chipsets, then
  586. you would have a series of #define's for them, and a variable `SDCchipset',
  587. which would be used throughout the driver when distinctions must be made.  See
  588. the Trident and PVGA1/WD drivers for examples (the Tseng ET3000 and ET4000 are
  589. counter-examples - these were implemented before the driver interface allowed
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  How to add an (S)VGA driver to XFree86
  599.  
  600.  
  601.  
  602. for multiple chipsets, so this example should NOT be followed).  Note that you
  603. should only distinguish versions when your driver needs to do things differ-
  604. ently for them.  For example, suppose the SDC driver supports the SDC-1a,
  605. SDC-1b, and SDC-2 chipsets.  The -1a and -1b are essentially the same, but dif-
  606. ferent from the -2 chipset.  Your driver should support the -1 and -2 chipsets,
  607. and not distinguish between the -1a and -1b.  This will simplify things for the
  608. end user.
  609.  
  610. In cases where you want to give the user control of driver behavior, or there
  611. are things that cannot be determined without user intervention, you should use
  612. ``option'' flags.  Say that board vendors that use the SDC chipsets have the
  613. option of providing 8 or 16 clocks.  There's no way you can determine this from
  614. the chipset probe, so you provide an option flag to let the user select the
  615. behavior from the XF86Config file.  The option flags are defined in the file
  616. ``xf86_option.h''.  You should look to see if there is already a flag that can
  617. be reused.  If so, use it in your driver.  If not, add a new #define, and
  618. define the string->symbol mapping in the table in that file.  To see how option
  619. flags are used, look at the ET4000, PVGA1/WD, and Trident drivers.
  620.  
  621. 6.2  Data Structures
  622.  
  623. Once you have an understanding of what is needed from the above description, it
  624. is time to fill in the driver data structures.    First we will deal with the
  625. `vgaSDCRec' structure.    This data structure is the driver-local structure that
  626. holds the SVGA state information.  The first entry in this data structure is
  627. ALWAYS `vgaHWRec std'.    This piece holds the generic VGA portion of the infor-
  628. mation.  After that, you will have one `unsigned char' field for each register
  629. that will be manipulated by your driver.  That's all there is to this data
  630. structure.
  631.  
  632. Next you must initialize the `SDC' structure (type `vgaVideoChipRec').    This is
  633. the global structure that identifies your driver to the server.  Its name MUST
  634. be `SDC', in all caps - i.e. it must match the directory name for your driver.
  635. This is required so that the Link Kit reconfiguration can identify all of the
  636. requisite directories and global data structures.
  637.  
  638. The first section of this structure simply holds pointers to the driver func-
  639. tions.
  640.  
  641. Next, you must initialize the information about how your chipset does bank
  642. switching.  The following fields must be filled in:
  643.  
  644.   1.          ChipMapSize - the amount of memory that must be mapped into the
  645.       server's address space.  This is almost always 64k (from 0xA0000 to
  646.       0xAFFFF).  Some chipsets use a 128k map (from 0xA0000 to 0xBFFFF).  If
  647.       your chipset gives an option, use the 64k window, as a 128k window rules
  648.       out using a Hercules or Monochrome Display Adapter card with the SVGA.
  649.  
  650.   2.          ChipSegmentSize - the size of each bank within the ChipMapSize
  651.       window.  This is usually also 64k, however, some chipsets split the
  652.       mapped window into a read portion and a write portion (for example the
  653.       PVGA1/Western Digital chipsets).
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  How to add an (S)VGA driver to XFree86
  665.  
  666.  
  667.  
  668.   3.          ChipSegmentShift - the number of bits by which an address will be
  669.       shifted right to mask of the bank number.  This is log-base-2 of ChipSeg-
  670.       mentSize.
  671.  
  672.   4.          ChipSegmentMask - a bitmask used to mask off the address within a
  673.       given bank.  This is (ChipSegmentSize-1).
  674.  
  675.   5.          ChipReadBottom,ChipReadTop - the addresses within the mapped win-
  676.       dow in which read operations can be done.  Usually 0, and 64k, respec-
  677.       tively, except for those chipset that have separate read and write win-
  678.       dows.
  679.  
  680.   6.          ChipWriteBottom,ChipWriteTop - same as above, for write opera-
  681.       tions.
  682.  
  683.   7.          ChipUse2Banks - a boolean value for whether this chipset has one
  684.       or two bank registers.  This is used to set up the screen-to-screen oper-
  685.       ations properly.
  686.  
  687. There are three more fields that must be filled in:
  688.  
  689.   1.          ChipInterlaceType - this is either VGA_NO_DIVIDE_VERT or
  690.       VGA_DIVIDE_VERT.    Some chipsets require that the vertical timing numbers
  691.       be divided in half for interlaced modes.    Setting this flag will take
  692.       care of that.
  693.  
  694.   2.          ChipOptionFlags - this should always be `{0,}' in the data struc-
  695.       ture initialization.  This is a bitfield that contains the Option flags
  696.       that are valid for this driver.  The appropriate bits are initialized at
  697.       the end of the Probe function.
  698.  
  699.   3.          ChipRounding - this gets set to the multiple by which the virtual
  700.       width of the display must be rounded for the 256-color server.  This
  701.       value is usually 8, but may be 4 or 16 for some chipsets.
  702.  
  703. 6.3  The Ident() function
  704.  
  705. The Ident() function is a very simple function.  The server will call this
  706. function repeatedly, until a NULL is returned, when printing out the list of
  707. configured drivers.  The Ident() function should return a chipset name for a
  708. supported chipset.  The function is passed a number which increments from 0 on
  709. each iteration.
  710.  
  711. 6.4  The ClockSelect() function
  712.  
  713. The ClockSelect() function is used during clock probing (i.e. when no `Clocks'
  714. line is specified in the XF86Config file) to select the dot-clock indicated by
  715. the number passed in the parameter.  The function should set the chipset's
  716. clock-select bits according to the passed-in number.  Two dummy values will be
  717. passed in as well (CLK_REG_SAVE, CLK_SAVE_RESTORE).  When CLK_REG_SAVE is
  718. passed, the function should save away copies of any registers that will be mod-
  719. ified during clock selection.  When CLK_REG_RESTORE is passed, the function
  720. should restore these registers.  This ensure that the clock-probing cannot cor-
  721. rupt registers.
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  How to add an (S)VGA driver to XFree86
  731.  
  732.  
  733.  
  734. This function should return FALSE if the passed-in index value is invalid or if
  735. the clock can't be set for some reason.
  736.  
  737. 6.5  The Probe() function
  738.  
  739. The Probe() function is perhaps the most important, and perhaps the least intu-
  740. itive function in the driver.  The Probe function is required to identify the
  741. chipset independent of all other chipsets.  If the user has specified a
  742. `Chipset' line in the XF86Config file, this is a simple string comparison
  743. check.    Otherwise, you must use some other technique to figure out what chipset
  744. is installed.  If you are lucky, the chipset will have an identification mecha-
  745. nism (ident/version registers, etc), and this will be documented in the data-
  746. book.  Otherwise, you will have to determine some scheme, using the reference
  747. materials listed below.
  748.  
  749. The identification is often done by looking for particular patterns in regis-
  750. ter, or for the existence of certain extended registers.  Or with some
  751. boards/chipsets, the requisite information can be obtained by reading the BIOS
  752. for certain signature strings.    The best advise is to study the existing probe
  753. functions, and use the reference documentation.  You must be certain that your
  754. probe is non-destructive - if you modify a register, it must be saved before,
  755. and restored after.
  756.  
  757. Once the chipset is successfully identified, the Probe() function must do some
  758. other initializations:
  759.  
  760.   1.          If the user has not specified the `VideoRam' parameter in the
  761.       XF86Config file, the amount of installed memory must be determined.
  762.  
  763.   2.          If the user has not specified the `Clocks' parameter in the
  764.       XF86Config file, the values for the available dot-clocks must be deter-
  765.       mined.  This is done by calling the vgaGetClocks() function, and passing
  766.       it the number of clocks available and a pointer to the ClockSelect()
  767.       function.
  768.  
  769.   3.          It is recommended that the `maxClock' field of the server's
  770.       `vga256InfoRec' structure be filled in with the maximum dot-clock rate
  771.       allowed for this chipset (specified in KHz).  If this is not filled in a
  772.       probe time, a default (currently 90MHz) will be used.
  773.  
  774.   4.          The `chipset' field of the server's `vga256InfoRec' structure
  775.       must be initialized to the name of the installed chipset.
  776.  
  777.   5.          If the driver will be used with the monochrome server, the
  778.       `bankedMono' field of the server's `vga256InfoRec' structure must be set
  779.       to indicate whether the monochrome driver supports banking.
  780.  
  781.   6.          If any option flags are used by this driver, the `ChipOption-
  782.       Flags' structure in the `vgaVideoChipRec' must be initialized with the
  783.       allowed option flags using the OFLG_SET() macro.
  784.  
  785. 6.6  The EnterLeave() function
  786.  
  787. The EnterLeave() function is called whenever the virtual console on which the
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  How to add an (S)VGA driver to XFree86
  797.  
  798.  
  799.  
  800. server runs is entered or left (for OSs without virtual consoles, the function
  801. is called when the server starts and again when it exits).  The purpose of this
  802. function is to enable and disable I/O permissions (for OSs where such is
  803. required), and to unlock and relock access to ``protected'' registers that the
  804. driver must manipulate.  It is a fairly trivial function, and can be imple-
  805. mented by following the comments in the stub driver.
  806.  
  807. 6.7  The Restore() function
  808.  
  809. The Restore() function is used for restoring a saved video state.  Note that
  810. `restore' is a bit of a misnomer - this function is used to both restore a
  811. saved state and to install a new one created by the server.  The Restore()
  812. function must complete the following actions:
  813.  
  814.   1.          Ensure that Bank 0 is selected, and that any other state informa-
  815.       tion required prior to writing out a new state has been set up.
  816.  
  817.   2.          Call vgaHWRestore() to restore the generic VGA portion of the
  818.       state information.  This function is in the vgaHW.c file.
  819.  
  820.   3.          Restore the chipset-specific portion of the state information.
  821.       This may be done by simply writing out the register, or by doing a
  822.       read/modify/write cycle if only certain bits are to be modified.    Be sure
  823.       to note the comment in the sample driver about how to handle clock-select
  824.       bits.
  825.  
  826. 6.8  The Save() function
  827.  
  828. The Save() function is used to extract the initial video state information when
  829. the server starts.  The Save() function must complete the following actions:
  830.  
  831.   1.          Ensure that Bank 0 is selected.
  832.  
  833.   2.          Call vgaHWSave() to extract the generic VGA portion of the state
  834.       information.  This function is in the vgaHW.c file.
  835.  
  836.   3.          Extract the chipset-specific portion of the state information.
  837.  
  838. 6.9  The Init() function
  839.  
  840. The Init() function is the second most important function in the driver (after
  841. the Probe() function).    It is used to initialize a data structure for each of
  842. the defined display modes in the server.  This function is required to initial-
  843. ize the entire `vgaSDCRec' data structure with the information needed to put
  844. the SVGA chipset into the required state.  The generic VGA portion of the
  845. structure is initialized with a call to vgaHWInit() (also located in vgaHW.c).
  846.  
  847. Once the generic portion is initialized, the Init() function can override any
  848. of the generic register initialization, if necessary.  All of the other fields
  849. are filled in with the correct initialization.    The information about the par-
  850. ticular mode being initialized is passed in the `mode' parameter, a pointer to
  851. a `DisplayModeRec' structure.  This can be dereferenced to determine the needed
  852. parameters.
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  How to add an (S)VGA driver to XFree86
  863.  
  864.  
  865.  
  866. If you only know how to initialize certain bits of the register, do that here,
  867. and make sure that the Restore() function does a read/modify/write to only
  868. manipulate those bits.    Again, refer to the existing drivers for examples of
  869. what happens in this function.
  870.  
  871. 6.10  The Adjust() function
  872.  
  873. The Adjust() function is another fairly basic function.  It is called whenever
  874. the server needs to adjust the start of the displayed part of the video memory,
  875. due to scrolling of the virtual screen or when changing the displayed resolu-
  876. tion.  All it does is set the starting address on the chipset to match the
  877. specified coordinate.  Follow the comments in the stub driver for details on
  878. how to implement it.
  879.  
  880. 6.11  The ValidMode() function
  881.  
  882. The ValidMode() function is required.  It is used to check for any chipset-
  883. dependent reasons why a graphics mode might not be valid.  It gets called by
  884. higher levels of the code after the Probe() stage.  In many cases no special
  885. checking will be required and this function will simply return TRUE always.
  886.  
  887. 6.12  The SaveScreen() function
  888.  
  889. The SaveScreen() function is not needed by most chipsets.  This function would
  890. only be required if the extended registers that your driver needs will be modi-
  891. fied when a synchronous reset is performed on the SVGA chipset (your databook
  892. should tell you this).    If you do NOT need this function, simply don't define
  893. it, and put `NoopDDA' in its place in the vgaVideoChipRec structure initializa-
  894. tion (NoopDDA is a generic-use empty function).
  895.  
  896. If you DO need this function, it is fairly simple to do.  It will be called
  897. twice - once before the reset, and again after.  It will be passed a parameter
  898. of SS_START in the former case, and SS_FINISH in the latter.  All that needs to
  899. be done is to save any registers that will be affected by the reset into static
  900. variables on the SS_START call, and then restore them on the SS_FINISH call.
  901.  
  902. 6.13  The GetMode() function
  903.  
  904. The GetMode() function is not used as of XFree86 1.3; its place in the
  905. vgaVideoChipRec should be initialized to `NoopDDA'.
  906.  
  907. At some point in the future, this function will be used to enable the server
  908. and/or a standalone program using the server's driver libraries to do interac-
  909. tive video mode adjustments.  This function will read the SVGA registers and
  910. fill in a DisplayModeRec structure with the current video mode.
  911.  
  912. 6.14  The FbInit() function
  913.  
  914. The FbInit() function is required for drivers with accelerated graphics sup-
  915. port.  It is used to replace default cfb.banked functions with accelerated
  916. chip-specific versions.  vga256LowlevFuncs is a struct containing a list of
  917. functions which can be replaced.  This struct defined in vga256.h.  Examples of
  918. FbInit() functions can be found in the et4000, pvga1 and cirrus drivers.
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  How to add an (S)VGA driver to XFree86
  929.  
  930.  
  931.  
  932. If you do NOT need this function, simply don't define it, and put `NoopDDA' in
  933. its place in the vgaVideoChipRec structure initialization.
  934.  
  935.  
  936. 7.  Building The New Server
  937.  
  938. As in the setup work, the steps for building the server depend whether you are
  939. working in the source tree or in the Link Kit.    Here are the steps for the ini-
  940. tial build after installing your new driver files:
  941.  
  942.    o If you are working in the source tree, follow these steps:
  943.  
  944.      Go to xc/programs/Xserver, and enter `make Makefile', then `make Makefiles
  945.      depend all'
  946.  
  947.    o If you are working in the Link Kit, follow these steps:
  948.  
  949.  
  950.        1.  Go to /usr/X11R6/lib/Server, and enter `./mkmf'
  951.  
  952.        2.  In the same directory, enter `make'
  953.  
  954. To rebuild the server after the initial build (e.g. after making changes to
  955. your driver):
  956.  
  957.    o      If you are working in the source tree, follow these steps:
  958.  
  959.        1.    Go to the appropriate drivers/ directory (e.g., xc/pro-
  960.        grams/Xserver/hw/xfree86/vga256/drivers), and enter `make'.
  961.  
  962.        2.    Go to xc/programs/Xserver, and enter `make loadXF86_SVGA' (to
  963.        link the color server), `make loadXF86_VGA16' (to link the 16 color
  964.        server) or `make loadXF86_Mono' (to link the mono server).
  965.  
  966.  
  967.    o      If you are working in the Link Kit, follow these steps:
  968.  
  969.  
  970.        1.    Go to the appropriate driver directory, and enter `make'.
  971.  
  972.        2.    Go to /usr/X11R6/lib/server, and enter `make loadXF86_SVGA' (to
  973.        link the color server) or `make loadXF86_VGA16' (to link the 16
  974.        color server) or `make loadXF86_Mono' (to link the mono server).
  975.  
  976.  
  977. 8.  Debugging
  978.  
  979. Debugging a new driver can be a painful experience, unfortunately.  It is
  980. likely that incorrect programming of the SVGA chipset can lock up your machine.
  981. More likely, however, is that the display will be lost, potentially requiring a
  982. reboot to correct.  It is HIGHLY recommended that the server be run from an
  983. attached terminal or a network login.  This is the only rational way in which a
  984. debugger can be used on the server.  Attempting to use multiple VTs for debug-
  985. ging is basically a waste of time.
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  How to add an (S)VGA driver to XFree86
  995.  
  996.  
  997.  
  998. Because of the potential for locking up the machine, it is a VERY good idea to
  999. remember to do a `sync' or two before starting the server.  In addition, any
  1000. unnecessary filesystems should be unmounted while the debugging session is
  1001. going on (to avoid having to run unnecessary fsck's).
  1002.  
  1003. By default the server is built without debugging symbols.  The server can grow
  1004. VERY large with debugging enabled.  It is very simple to rebuild your driver
  1005. for debugging, though.    Do the following:
  1006.  
  1007.   1.  Go to the driver directory.
  1008.  
  1009.   2.  Edit the Makefile.  Look for the SECOND definition of `CDEBUGFLAGS'.
  1010.       Change this definition to
  1011.  
  1012.              CDEBUGFLAGS = -g -DNO_INLINE
  1013.  
  1014.  
  1015.  
  1016.  
  1017.       (this will enable debugging symbols and disable inlining of functions,
  1018.       which can make single-stepping a nightmare).
  1019.  
  1020.   3.  Remove the `sdc_driver.o' file.
  1021.  
  1022.   4.  Now follow the steps above for rebuilding the server.
  1023.  
  1024.       (Alternatively, instead of editing the Makefile, you can simply do `make
  1025.       CDEBUGFLAGS="-g -DNO_INLINE"' after removing the old .o file, then
  1026.       rebuild the server as described above).
  1027.  
  1028. This will give you a server with which you can set breakpoints in the driver
  1029. functions and single-step them.  If you are working in the source tree, and
  1030. just learning about SVGA programming, it may be useful to rebuild vgaHW.c with
  1031. debugging as well.
  1032.  
  1033.  
  1034. 9.  Advice
  1035.  
  1036. I cannot stress this enough - study all available references, and the existing
  1037. code, until you understand what is happening.  Do this BEFORE you begin writing
  1038. a driver.  This will save you a massive amount of headache.  Try to find a
  1039. driver for a chipset that is similar to yours, if possible.  Use this as an
  1040. example, and perhaps derive your driver from it.
  1041.  
  1042. Do not let the gloom-and-doom in the debugging section    discourage you.  While
  1043. you will probably have problems initially (I still do), careful, deliberate
  1044. debugging steps can bear fruit very quickly.  It is likely that, given a good
  1045. understanding of the chipset, a driver can be written and debugged in a day or
  1046. two.  For someone just learning about this kind of programming, a week is more
  1047. reasonable.
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  How to add an (S)VGA driver to XFree86
  1061.  
  1062.  
  1063.  
  1064. 10.  Advanced Topics
  1065.  
  1066. Newer chipsets are getting into two advanced areas: programmable clock genera-
  1067. tors, and accelerated capabilities (BitBlt, line drawing, HW cursor).  These
  1068. are new areas, and the formal interfaces to them are not yet defined.  It is
  1069. advised that you contact the XFree86 team and get involved with the develop-
  1070. ment/beta-testing team if you need to be working in these areas.
  1071.  
  1072.  
  1073. 11.  References
  1074.  
  1075.    o Programmer's Guide to the EGA and VGA Cards, 3rd ed.
  1076.  
  1077.      Richard Ferraro
  1078.  
  1079.      Addison-Wesley, 1994
  1080.  
  1081.      ISBN 0-201-62490-7
  1082.  
  1083.      (This is the bible of SVGA programming - it has a few errors, so watch
  1084.      out.  The third edition also covers several accelerated video cards.)
  1085.  
  1086.    o vgadoc4.zip
  1087.  
  1088.      Finn Thoegersen
  1089.  
  1090.      (This is a collection of SVGA and other chipset documentation.  It is
  1091.      available on most MS-DOS/Windows related FTP archives, including
  1092.      wuarchive.  It is DOS/BIOS oriented, but is still extremely useful, espe-
  1093.      cially for developing probe functions.)
  1094.  
  1095.  
  1096. 12.  Vendor Contact Information
  1097.  
  1098.       ATI Technologies (VGA-Wonder, Mach8, Mach32)
  1099.          33 Commerce Valley Drive East" Thornhill, Ontario
  1100.  
  1101.         Canada L3T 7N6
  1102.  
  1103.         (905) 882-2600 (sales)
  1104.  
  1105.         (905) 882-2626 (tech support)
  1106.  
  1107.         (905) 764-9404 (BBS)
  1108.  
  1109.         (905) 882-0546 (fax)
  1110.  
  1111.       Chips & Technologies
  1112.         ???
  1113.  
  1114.       Cirrus Logic (SVGA, Accelerators - CL-GD5426)
  1115.         3100 West Warren Ave.
  1116.  
  1117.         Fremont, CA  94538
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  How to add an (S)VGA driver to XFree86
  1127.  
  1128.  
  1129.  
  1130.         (510) 623-8300 (N. CA, USA)
  1131.  
  1132.         (49) 8152-40084 (Germany)
  1133.  
  1134.         (44) 0727-872424 (UK)
  1135.  
  1136.       Genoa Systems (GVGA)
  1137.         75 E. Trimble Road
  1138.  
  1139.         San Jose, CA 95131
  1140.  
  1141.         (408) 432-9090 (sales)
  1142.  
  1143.         (408) 432-8324 (tech support)
  1144.  
  1145.       Headland Technologies, Inc (Video-7 VGA 1024i, VRAM II)
  1146.         46221 Landing Parkway
  1147.  
  1148.         Fremont, CA  94538
  1149.  
  1150.         (415) 623-7857
  1151.  
  1152.       Oak Technology, Inc (OTI-067,OTI-077)
  1153.         139 Kifer Ct.
  1154.  
  1155.         Sunnyvale, CA 94086
  1156.  
  1157.         (408) 737-0888
  1158.  
  1159.         (408) 737-3838 (fax)
  1160.  
  1161.       S3 (911, 924, 801/805, 928, 864, 868, 964, 968, 764, 765)
  1162.         (408) 980-5400
  1163.  
  1164.       Trident Microsystems Inc (8800, 8900, 9000)
  1165.         205 Ravendale Dr
  1166.  
  1167.         Mountainside, CA 94043
  1168.  
  1169.         (415) 691-9211
  1170.  
  1171.       Tseng Labs Inc,
  1172.         6 Terry Drive
  1173.  
  1174.         Newtown, PA  18940
  1175.  
  1176.         (215) 968-0502
  1177.  
  1178.       Weitek (Power9000, 5186)
  1179.         1060 E. Arques Ave,
  1180.  
  1181.         Sunnyvale, CA  94086
  1182.  
  1183.         (408) 738-5765
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  How to add an (S)VGA driver to XFree86
  1193.  
  1194.  
  1195.  
  1196.       Western Digital
  1197.         (714) 932-4900
  1198.  
  1199.      Generated from XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml,v 3.13 1997/01/25 03:22:16 dawes Exp $
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.      $XConsortium: VGADriv.sgml /main/9 1996/10/28 05:13:22 kaleb $
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  How to add an (S)VGA driver to XFree86
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.                    CONTENTS
  1329.  
  1330.  
  1331.  
  1332. 1.  Introduction  ........................................................... 1
  1333.  
  1334. 2.  Getting Started  ........................................................ 1
  1335.  
  1336. 3.  Directory Tree Structure  ............................................... 2
  1337.  
  1338. 4.  Setting Up The Build Information  ....................................... 4
  1339.  
  1340. 5.  The Bank-Switching Functions  ........................................... 6
  1341.  
  1342. 6.  The Driver Itself  ...................................................... 8
  1343.     6.1  Multiple Chipsets And Options    ..................................... 9
  1344.     6.2  Data Structures  .................................................. 10
  1345.     6.3  The Ident() function  ............................................. 11
  1346.     6.4  The ClockSelect() function  ....................................... 11
  1347.     6.5  The Probe() function  ............................................. 12
  1348.     6.6  The EnterLeave() function  ........................................ 12
  1349.     6.7  The Restore() function  ........................................... 13
  1350.     6.8  The Save() function  .............................................. 13
  1351.     6.9  The Init() function  .............................................. 13
  1352.     6.10 The Adjust() function    ............................................ 14
  1353.     6.11 The ValidMode() function  ......................................... 14
  1354.     6.12 The SaveScreen() function  ........................................ 14
  1355.     6.13 The GetMode() function  ........................................... 14
  1356.     6.14 The FbInit() function    ............................................ 14
  1357.  
  1358. 7.  Building The New Server  ............................................... 15
  1359.  
  1360. 8.  Debugging  ............................................................. 15
  1361.  
  1362. 9.  Advice  ................................................................ 16
  1363.  
  1364. 10. Advanced Topics  ....................................................... 17
  1365.  
  1366. 11. References    ............................................................ 17
  1367.  
  1368. 12. Vendor Contact Information    ............................................ 17
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.                        i
  1385.  
  1386.  
  1387.